package classdiagram.diagram.part;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.runtime.notation.View;

import classdiagram.Attribute;
import classdiagram.Class;
import classdiagram.ClassDiagram;
import classdiagram.ClassdiagramPackage;
import classdiagram.Operation;
import classdiagram.Relation;
import classdiagram.diagram.edit.parts.AttributeEditPart;
import classdiagram.diagram.edit.parts.ClassAttributeCompartmentEditPart;
import classdiagram.diagram.edit.parts.ClassDiagramEditPart;
import classdiagram.diagram.edit.parts.ClassEditPart;
import classdiagram.diagram.edit.parts.ClassOperationCompartmentEditPart;
import classdiagram.diagram.edit.parts.OperationEditPart;
import classdiagram.diagram.edit.parts.RelationEditPart;
import classdiagram.diagram.providers.ClassDiagramElementTypes;

/**
 * @generated
 */
public class ClassDiagramDiagramUpdater {

	/**
	 * @generated
	 */
	public static List<ClassDiagramNodeDescriptor> getSemanticChildren(View view) {
		switch (ClassDiagramVisualIDRegistry.getVisualID(view)) {
		case ClassDiagramEditPart.VISUAL_ID:
			return getClassDiagram_1000SemanticChildren(view);
		case ClassAttributeCompartmentEditPart.VISUAL_ID:
			return getClassAttributeCompartment_7001SemanticChildren(view);
		case ClassOperationCompartmentEditPart.VISUAL_ID:
			return getClassOperationCompartment_7002SemanticChildren(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramNodeDescriptor> getClassDiagram_1000SemanticChildren(
			View view) {
		if (!view.isSetElement()) {
			return Collections.emptyList();
		}
		ClassDiagram modelElement = (ClassDiagram) view.getElement();
		LinkedList<ClassDiagramNodeDescriptor> result = new LinkedList<ClassDiagramNodeDescriptor>();
		for (Iterator<?> it = modelElement.getClasses().iterator(); it
				.hasNext();) {
			Class childElement = (Class) it.next();
			int visualID = ClassDiagramVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == ClassEditPart.VISUAL_ID) {
				result.add(new ClassDiagramNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramNodeDescriptor> getClassAttributeCompartment_7001SemanticChildren(
			View view) {
		if (false == view.eContainer() instanceof View) {
			return Collections.emptyList();
		}
		View containerView = (View) view.eContainer();
		if (!containerView.isSetElement()) {
			return Collections.emptyList();
		}
		Class modelElement = (Class) containerView.getElement();
		LinkedList<ClassDiagramNodeDescriptor> result = new LinkedList<ClassDiagramNodeDescriptor>();
		for (Iterator<?> it = modelElement.getAttributtes().iterator(); it
				.hasNext();) {
			Attribute childElement = (Attribute) it.next();
			int visualID = ClassDiagramVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == AttributeEditPart.VISUAL_ID) {
				result.add(new ClassDiagramNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramNodeDescriptor> getClassOperationCompartment_7002SemanticChildren(
			View view) {
		if (false == view.eContainer() instanceof View) {
			return Collections.emptyList();
		}
		View containerView = (View) view.eContainer();
		if (!containerView.isSetElement()) {
			return Collections.emptyList();
		}
		Class modelElement = (Class) containerView.getElement();
		LinkedList<ClassDiagramNodeDescriptor> result = new LinkedList<ClassDiagramNodeDescriptor>();
		for (Iterator<?> it = modelElement.getOperations().iterator(); it
				.hasNext();) {
			Operation childElement = (Operation) it.next();
			int visualID = ClassDiagramVisualIDRegistry.getNodeVisualID(view,
					childElement);
			if (visualID == OperationEditPart.VISUAL_ID) {
				result.add(new ClassDiagramNodeDescriptor(childElement,
						visualID));
				continue;
			}
		}
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getContainedLinks(View view) {
		switch (ClassDiagramVisualIDRegistry.getVisualID(view)) {
		case ClassDiagramEditPart.VISUAL_ID:
			return getClassDiagram_1000ContainedLinks(view);
		case ClassEditPart.VISUAL_ID:
			return getClass_2001ContainedLinks(view);
		case AttributeEditPart.VISUAL_ID:
			return getAttribute_3001ContainedLinks(view);
		case OperationEditPart.VISUAL_ID:
			return getOperation_3002ContainedLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001ContainedLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getIncomingLinks(View view) {
		switch (ClassDiagramVisualIDRegistry.getVisualID(view)) {
		case ClassEditPart.VISUAL_ID:
			return getClass_2001IncomingLinks(view);
		case AttributeEditPart.VISUAL_ID:
			return getAttribute_3001IncomingLinks(view);
		case OperationEditPart.VISUAL_ID:
			return getOperation_3002IncomingLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001IncomingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getOutgoingLinks(View view) {
		switch (ClassDiagramVisualIDRegistry.getVisualID(view)) {
		case ClassEditPart.VISUAL_ID:
			return getClass_2001OutgoingLinks(view);
		case AttributeEditPart.VISUAL_ID:
			return getAttribute_3001OutgoingLinks(view);
		case OperationEditPart.VISUAL_ID:
			return getOperation_3002OutgoingLinks(view);
		case RelationEditPart.VISUAL_ID:
			return getRelation_4001OutgoingLinks(view);
		}
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getClassDiagram_1000ContainedLinks(
			View view) {
		ClassDiagram modelElement = (ClassDiagram) view.getElement();
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		result.addAll(getContainedTypeModelFacetLinks_Relation_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getClass_2001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getAttribute_3001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getOperation_3002ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getRelation_4001ContainedLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getClass_2001IncomingLinks(
			View view) {
		Class modelElement = (Class) view.getElement();
		Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences = EcoreUtil.CrossReferencer
				.find(view.eResource().getResourceSet().getResources());
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		result.addAll(getIncomingTypeModelFacetLinks_Relation_4001(
				modelElement, crossReferences));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getAttribute_3001IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getOperation_3002IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getRelation_4001IncomingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getClass_2001OutgoingLinks(
			View view) {
		Class modelElement = (Class) view.getElement();
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		result.addAll(getOutgoingTypeModelFacetLinks_Relation_4001(modelElement));
		return result;
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getAttribute_3001OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getOperation_3002OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	public static List<ClassDiagramLinkDescriptor> getRelation_4001OutgoingLinks(
			View view) {
		return Collections.emptyList();
	}

	/**
	 * @generated
	 */
	private static Collection<ClassDiagramLinkDescriptor> getContainedTypeModelFacetLinks_Relation_4001(
			ClassDiagram container) {
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		for (Iterator<?> links = container.getRelations().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Relation) {
				continue;
			}
			Relation link = (Relation) linkObject;
			if (RelationEditPart.VISUAL_ID != ClassDiagramVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Class dst = link.getDestination();
			Class src = link.getOrigin();
			result.add(new ClassDiagramLinkDescriptor(src, dst, link,
					ClassDiagramElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<ClassDiagramLinkDescriptor> getIncomingTypeModelFacetLinks_Relation_4001(
			Class target,
			Map<EObject, Collection<EStructuralFeature.Setting>> crossReferences) {
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		Collection<EStructuralFeature.Setting> settings = crossReferences
				.get(target);
		for (EStructuralFeature.Setting setting : settings) {
			if (setting.getEStructuralFeature() != ClassdiagramPackage.eINSTANCE
					.getRelation_Destination()
					|| false == setting.getEObject() instanceof Relation) {
				continue;
			}
			Relation link = (Relation) setting.getEObject();
			if (RelationEditPart.VISUAL_ID != ClassDiagramVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Class src = link.getOrigin();
			result.add(new ClassDiagramLinkDescriptor(src, target, link,
					ClassDiagramElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

	/**
	 * @generated
	 */
	private static Collection<ClassDiagramLinkDescriptor> getOutgoingTypeModelFacetLinks_Relation_4001(
			Class source) {
		ClassDiagram container = null;
		// Find container element for the link.
		// Climb up by containment hierarchy starting from the source
		// and return the first element that is instance of the container class.
		for (EObject element = source; element != null && container == null; element = element
				.eContainer()) {
			if (element instanceof ClassDiagram) {
				container = (ClassDiagram) element;
			}
		}
		if (container == null) {
			return Collections.emptyList();
		}
		LinkedList<ClassDiagramLinkDescriptor> result = new LinkedList<ClassDiagramLinkDescriptor>();
		for (Iterator<?> links = container.getRelations().iterator(); links
				.hasNext();) {
			EObject linkObject = (EObject) links.next();
			if (false == linkObject instanceof Relation) {
				continue;
			}
			Relation link = (Relation) linkObject;
			if (RelationEditPart.VISUAL_ID != ClassDiagramVisualIDRegistry
					.getLinkWithClassVisualID(link)) {
				continue;
			}
			Class dst = link.getDestination();
			Class src = link.getOrigin();
			if (src != source) {
				continue;
			}
			result.add(new ClassDiagramLinkDescriptor(src, dst, link,
					ClassDiagramElementTypes.Relation_4001,
					RelationEditPart.VISUAL_ID));
		}
		return result;
	}

}
